package com.example.demo.util;


import com.baomidou.mybatisplus.core.metadata.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.annotation.SortableColumn;
import com.example.demo.exception.CustomException;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 获取分页参数工具类
 *
 * @author renliang
 */
public class PageUtil {
    public static final String Q_SORT_BY = "sortBy";
    public static final String Q_SORT_TYPE = "sortType";
    public static final String DESC = "desc";

    public static final String PAGE_NUM = "pageNum";
    /**
     * 每页显示记录数
     */
    public static final String PAGE_SIZE = "pageSize";


    /**
     * 取分页参数及排序字段
     *
     * @param clazz mybatis-plus的实体类，不能是其子类
     * @return 分页及排序参数
     */
    public static <T> IPage<T> getPage(Class<T> clazz) {

        Integer pageNum = ServletUtils.getParameterToInt(PAGE_NUM);
        Integer pageSize = ServletUtils.getParameterToInt(PAGE_SIZE);
        pageNum = pageNum == null ? 0 : pageNum;
        pageSize = pageSize == null ? 10 : pageSize;
        Page<T> page = new Page<>(pageNum, pageSize);
        String sortByStr = ServletUtils.getParameter(Q_SORT_BY);
        String sortTypeStr = ServletUtils.getParameter(Q_SORT_TYPE);
        if (!StringUtils.hasText(sortByStr)) {
            return page;
        }
        String[] sortBy = sortByStr.split(",");
        String[] sortType = StringUtils.hasText(sortTypeStr) ? sortTypeStr.split(",") : new String[0];
        for (int i = 0; i < sortBy.length; i++) {
            boolean asc = i >= sortType.length || !DESC.equals(sortType[i]);
            page.addOrder(new OrderItem(sortBy[i], asc));
        }
        processAndValidateSortFields(clazz, page.orders());
        return page;
    }

    public static <T> IPage<T> getPage(Integer pageNo, Integer pageSize) {
        pageNo = pageNo == null ? 0 : pageNo;
        pageSize = pageSize == null ? 10 : pageSize;
        return new Page<>(pageNo, pageSize);
    }

    private static <T> void processAndValidateSortFields(Class<T> clazz, List<OrderItem> orders) {
        if (CollectionUtils.isEmpty(orders)) {
            return;
        }
        final TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
        final List<TableFieldInfo> fieldList = tableInfo == null ? null : tableInfo.getFieldList();

        for (OrderItem oi : orders) {
            if (tableInfo != null && tableInfo.getKeyProperty().equals(oi.getColumn())) {
                oi.setColumn(tableInfo.getKeyColumn());
                continue;
            }

            String found = null;

            if (fieldList != null) {
                for (TableFieldInfo fi : fieldList) {
                    if (fi.getProperty().equals(oi.getColumn())) {
                        found = fi.getColumn();
                        break;
                    }
                }
            }

            if (found == null) {
                // 检查该字段有没有 @SortableColumn 注解
                final Field field = ReflectionUtils.findField(clazz, oi.getColumn());
                if (field != null) {
                    final SortableColumn sortableColumn = field.getAnnotation(SortableColumn.class);
                    if (sortableColumn != null) {
                        found = sortableColumn.value();
                        if (!StringUtils.hasText(found)) {
                            found = oi.getColumn();
                        }
                    }
                }
            }
            if (found == null) {
                throw new CustomException("不存在的字段名: " + oi.getColumn());
            }
            oi.setColumn(found);
        }
    }
}
